package com.yanqu.road.entity.activity.apprentice.data;

import com.yanqu.road.entity.DataObject;
import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.FieldTypeAnnotation;
import com.yanqu.road.entity.activity.apprentice.ApprenticeEffectBuffProject;
import com.yanqu.road.entity.activity.apprentice.ApprenticeTalentData;
import com.yanqu.road.entity.enums.eOccupationType;
import com.yanqu.road.utils.FixSizeLinkedList;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

@FieldTypeAnnotation(tableName = "t_c_activity_apprentice_user_data", desc = "爱徒养成-玩家数据表")
public class ApprenticeUserData extends DataObject {

    @FieldTypeAnnotation(desc = "活动ID", select = true, update = true)
    private int activityId;

    @FieldTypeAnnotation(desc = "玩家ID", select = true, update = true)
    private long userId;

    @FieldTypeAnnotation(desc = "区服ID")
    private long serverId;

    @FieldTypeAnnotation(desc = "商会ID")
    private String unionId;

    @FieldTypeAnnotation(desc = "学业评级")
    private int level;

    @FieldTypeAnnotation(desc = "行程次数")
    private int programNum;

    @FieldTypeAnnotation(desc = "士")
    private long talent1;

    @FieldTypeAnnotation(desc = "农")
    private long talent2;

    @FieldTypeAnnotation(desc = "工")
    private long talent3;

    @FieldTypeAnnotation(desc = "商")
    private long talent4;

    @FieldTypeAnnotation(desc = "侠")
    private long talent5;

    @FieldTypeAnnotation(desc = "待选择的项目集合")
    private List<Integer> waitProjects = new ArrayList<>();

    @FieldTypeAnnotation(desc = "本次生效的buff项目集合")
    private List<ApprenticeBuffProjectData> buffProjectIds = new ArrayList<>();

    @FieldTypeAnnotation(desc = "距离小考还差多少行程")
    private int examDiffNum;

    @FieldTypeAnnotation(desc = "当前小考数据")
    private ApprenticeUserExamData examData;

    @FieldTypeAnnotation(desc = "发起的宴请世家次数")
    private int startBanquetNum;

    @FieldTypeAnnotation(desc = "可被宴请的次数")
    private int canBeBanquetNum;

    @FieldTypeAnnotation(desc = "下次生效buff,用于显示用")
    private List<ApprenticeEffectBuffProject> nextEffectProject = new ArrayList<>();

    @FieldTypeAnnotation(desc = "创建时间")
    private long createTime;

    /**
     * 玩家锁
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 天资辩学日志
     */
    private List<ApprenticeUserPvpLog> pvpLogs = new FixSizeLinkedList<>(50);

    /**
     * 天资辩学日志红点
     */
    private boolean pvpRedFlag = false;

    /**
     * 宴请世家日志
     */
    private List<ApprenticeUserBanquetLog> banquetLogs = new FixSizeLinkedList<>(50);

    /**
     * 宴请世家日志红点
     */
    private boolean banquetRedFlag = false;

    public ApprenticeUserData() {
    }

    public ApprenticeUserData(int activityId, long userId, long serverId, String unionId, int examDiffNum, ApprenticeUserExamData examData, int canBeBanquetNum) {
        this.activityId = activityId;
        this.userId = userId;
        this.serverId = serverId;
        this.unionId = unionId;
        this.level = 1;
        this.programNum = 0;
        this.talent1 = 0;
        this.talent2 = 0;
        this.talent3 = 0;
        this.talent4 = 0;
        this.talent5 = 0;
        this.waitProjects = new ArrayList<>();
        this.buffProjectIds = new ArrayList<>();
        this.examDiffNum = examDiffNum;
        this.examData = examData;
        this.startBanquetNum = 0;
        this.canBeBanquetNum = canBeBanquetNum;
        this.nextEffectProject = new ArrayList<>();
        this.createTime = System.currentTimeMillis();
        setInsertOption();
    }

    public int getActivityId() {
        return activityId;
    }
    public void setActivityId(int activityId) {
        if (this.activityId != activityId) {
            this.activityId = activityId;
            setOp(DataStatus.Update);
        }
    }

    public long getUserId() {
        return userId;
    }
    public void setUserId(long userId) {
        if (this.userId != userId) {
            this.userId = userId;
            setOp(DataStatus.Update);
        }
    }

    public long getServerId() {
        return serverId;
    }

    public void setServerId(long serverId) {
        if (this.serverId != serverId) {
            this.serverId = serverId;
            setOp(DataStatus.Update);
        }
    }

    public String getUnionId() {
        return unionId;
    }

    public void setUnionId(String unionId) {
        if (this.unionId != unionId) {
            this.unionId = unionId;
            setOp(DataStatus.Update);
        }
    }

    public int getLevel() {
        return level;
    }
    public void setLevel(int level) {
        if (this.level != level) {
            this.level = level;
            setOp(DataStatus.Update);
        }
    }

    public int getProgramNum() {
        return programNum;
    }

    public void setProgramNum(int programNum) {
        if (this.programNum != programNum) {
            this.programNum = programNum;
            setOp(DataStatus.Update);
        }
    }

    public long getTalent1() {
        return talent1;
    }
    public void setTalent1(long talent1) {
        if (this.talent1 != talent1) {
            this.talent1 = talent1;
            setOp(DataStatus.Update);
        }
    }

    public long getTalent2() {
        return talent2;
    }
    public void setTalent2(long talent2) {
        if (this.talent2 != talent2) {
            this.talent2 = talent2;
            setOp(DataStatus.Update);
        }
    }

    public long getTalent3() {
        return talent3;
    }
    public void setTalent3(long talent3) {
        if (this.talent3 != talent3) {
            this.talent3 = talent3;
            setOp(DataStatus.Update);
        }
    }

    public long getTalent4() {
        return talent4;
    }
    public void setTalent4(long talent4) {
        if (this.talent4 != talent4) {
            this.talent4 = talent4;
            setOp(DataStatus.Update);
        }
    }

    public long getTalent5() {
        return talent5;
    }
    public void setTalent5(long talent5) {
        if (this.talent5 != talent5) {
            this.talent5 = talent5;
            setOp(DataStatus.Update);
        }
    }

    public List<Integer> getWaitProjects() {
        return waitProjects;
    }
    public void setWaitProjects(List<Integer> waitProjects) {
        if (null == waitProjects){
            return;
        }
        if (this.waitProjects == null || !this.waitProjects.equals(waitProjects)) {
            this.waitProjects = waitProjects;
            setOp(DataStatus.Update);
        }
    }

    public List<ApprenticeBuffProjectData> getBuffProjectIds() {
        return buffProjectIds;
    }

    public void setBuffProjectIds(List<ApprenticeBuffProjectData> buffProjectIds) {
        if (null == buffProjectIds){
            return;
        }
        if (this.buffProjectIds == null || !this.buffProjectIds.equals(buffProjectIds)) {
            this.buffProjectIds = buffProjectIds;
            setOp(DataStatus.Update);
        }
    }

    public synchronized void addBuffProjectId(int projectId, int num) {
        ApprenticeBuffProjectData buffProjectData = new ApprenticeBuffProjectData(projectId, num);
        this.buffProjectIds.add(buffProjectData);
        setOp(DataStatus.Update);
    }

    public int getExamDiffNum() {
        return examDiffNum;
    }
    public void setExamDiffNum(int examDiffNum) {
        if (this.examDiffNum != examDiffNum) {
            this.examDiffNum = examDiffNum;
            setOp(DataStatus.Update);
        }
    }

    public synchronized void reExamDiffNum() {
        this.examDiffNum = this.examDiffNum - 1;
        setOp(DataStatus.Update);
    }

    public ApprenticeUserExamData getExamData() {
        return examData;
    }
    public void setExamData(ApprenticeUserExamData examData) {
        if (null == examData){
            return;
        }
        if (this.examData == null || !this.examData.equals(examData)) {
            this.examData = examData;
            setOp(DataStatus.Update);
        }
    }

    public int getStartBanquetNum() {
        return startBanquetNum;
    }

    public void setStartBanquetNum(int startBanquetNum) {
        if (this.startBanquetNum != startBanquetNum) {
            this.startBanquetNum = startBanquetNum;
            setOp(DataStatus.Update);
        }
    }

    public int getCanBeBanquetNum() {
        return canBeBanquetNum;
    }

    public void setCanBeBanquetNum(int canBeBanquetNum) {
        if (this.canBeBanquetNum != canBeBanquetNum) {
            this.canBeBanquetNum = canBeBanquetNum;
            setOp(DataStatus.Update);
        }
    }

    public List<ApprenticeEffectBuffProject> getNextEffectProject() {
        return nextEffectProject;
    }

    public void setNextEffectProject(List<ApprenticeEffectBuffProject> nextEffectProject) {
        this.nextEffectProject = nextEffectProject;
    }

    public void addNextEffectProject(ApprenticeEffectBuffProject nextEffectProject) {
        this.nextEffectProject.add(nextEffectProject);
        setOp(DataStatus.Update);
    }

    public void clearNextEffectProject() {
        this.nextEffectProject.clear();
        setOp(DataStatus.Update);
    }

    public long getCreateTime() {
        return createTime;
    }
    public void setCreateTime(long createTime) {
        if (this.createTime != createTime) {
            this.createTime = createTime;
            setOp(DataStatus.Update);
        }
    }

    public ReentrantLock getLock() {
        return lock;
    }

    /**
     * 添加天资
     * @param type 0:随机天资
     * @param talent
     */
    public synchronized ApprenticeTalentData addTalent(int type, long talent, boolean addExam) {
        if (eOccupationType.Scholar.getValue() == type) {
            this.talent1 += talent;
            this.setTalent1(this.talent1);
        } else if (eOccupationType.Farmer.getValue() == type) {
            this.talent2 += talent;
            this.setTalent2(this.talent2);
        } else if (eOccupationType.Craftsman.getValue() == type) {
            this.talent3 += talent;
            this.setTalent3(this.talent3);
        } else if (eOccupationType.Businessman.getValue() == type) {
            this.talent4 += talent;
            this.setTalent4(this.talent4);
        } else if (eOccupationType.Knight.getValue() == type) {
            this.talent5 += talent;
            this.setTalent5(this.talent5);
        }

        //小考添加天资
        if (addExam && this.examData != null) {
            this.examData.addTalent(type, talent);
        }

        return new ApprenticeTalentData(type, talent);
    }

    /**
     * 获取最高的天资职业
     * @return
     */
    public int getMaxTalentType() {
        long maxTalent = this.talent1;
        int maxTalentType = eOccupationType.Scholar.getValue();
        if (this.talent2 > maxTalent) {
            maxTalent = this.talent2;
            maxTalentType = eOccupationType.Farmer.getValue();
        }
        if (this.talent3 > maxTalent) {
            maxTalent = this.talent3;
            maxTalentType = eOccupationType.Craftsman.getValue();
        }
        if (this.talent4 > maxTalent) {
            maxTalent = this.talent4;
            maxTalentType = eOccupationType.Businessman.getValue();
        }
        if (this.talent5 > maxTalent) {
            maxTalent = this.talent5;
            maxTalentType = eOccupationType.Knight.getValue();
        }
        return maxTalentType;
    }

    /**
     * 获取天资，根据类型
     * @param talentType
     * @return
     */
    public long getTalentByType(int talentType) {
        if (talentType == eOccupationType.Scholar.getValue()) {
            return talent1;
        }
        if (talentType == eOccupationType.Farmer.getValue()) {
            return talent2;
        }
        if (talentType == eOccupationType.Craftsman.getValue()) {
            return talent3;
        }
        if (talentType == eOccupationType.Businessman.getValue()) {
            return talent4;
        }
        if (talentType == eOccupationType.Knight.getValue()) {
            return talent5;
        }
        return 0;
    }

    /**
     * 获取总天资
     * @return
     */
    public long getAllTalent() {
        return talent1 + talent2 + talent3 + talent4 + talent5;
    }

    /**
     * 获取当前buffID列表
     * @return
     */
    public List<Integer> getBuffProjectIdList() {
        List<Integer> projectIds = new ArrayList<>();
        for (ApprenticeBuffProjectData buffProjectData : buffProjectIds) {
            if (buffProjectData.getNum() > 0) {
                projectIds.add(buffProjectData.getProjectId());
            }
        }
        return projectIds;
    }

    public List<ApprenticeUserPvpLog> getPvpLogs() {
        return pvpLogs;
    }

    public void setPvpLogs(List<ApprenticeUserPvpLog> pvpLogs) {
        this.pvpLogs = pvpLogs;
    }

    public void addPvpLog(ApprenticeUserPvpLog pvpLog) {
        this.pvpLogs.add(pvpLog);
        this.pvpRedFlag = true;
    }

    public List<ApprenticeUserBanquetLog> getBanquetLogs() {
        return banquetLogs;
    }

    public void setBanquetLogs(List<ApprenticeUserBanquetLog> banquetLogs) {
        this.banquetLogs = banquetLogs;
    }

    public void addBanquetLog(ApprenticeUserBanquetLog banquetLog) {
        this.banquetLogs.add(banquetLog);
        this.banquetRedFlag = true;
    }

    public boolean isPvpRedFlag() {
        return pvpRedFlag;
    }

    public void setPvpRedFlag(boolean pvpRedFlag) {
        this.pvpRedFlag = pvpRedFlag;
    }

    public boolean isBanquetRedFlag() {
        return banquetRedFlag;
    }

    public void setBanquetRedFlag(boolean banquetRedFlag) {
        this.banquetRedFlag = banquetRedFlag;
    }

    /**
     * 天资转string
     * @return
     */
    public String talentToSting() {
        List<String> list = new ArrayList<>();
        list.add(eOccupationType.Scholar.getValue() + ":" + this.talent1);
        list.add(eOccupationType.Farmer.getValue() + ":" + this.talent2);
        list.add(eOccupationType.Craftsman.getValue() + ":" + this.talent3);
        list.add(eOccupationType.Businessman.getValue() + ":" + this.talent4);
        list.add(eOccupationType.Knight.getValue() + ":" + this.talent5);
        return StringUtils.listToString(list, ",");
    }
}
